package cc.yugu.yhdw.webserver.service.basic;

import cc.yugu.yhdw.common.domain.basic.Dept;
import cc.yugu.yhdw.common.entity.json.ExtResult;
import cc.yugu.yhdw.common.entity.pagination.Page;
import cc.yugu.yhdw.common.entity.tree.Node;
import cc.yugu.yhdw.common.entity.tree.NodeModel;
import cc.yugu.yhdw.common.service.AbstractService;
import cc.yugu.yhdw.common.utils.YhdwUtils;
import cc.yugu.yhdw.webserver.config.AppConfig;
import cc.yugu.yhdw.webserver.persistence.basic.AgentMapper;
import cc.yugu.yhdw.webserver.persistence.basic.DeptMapper;
import cc.yugu.yhdw.webserver.persistence.basic.UserMapper;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
/**
 * 部门业务
 *
 * @Date:Created in 2018/7/3 15:36
 * @Author:
 * @Modified By: zjn 2018/7/3 15:36
 */
@Service
public class DeptService extends AbstractService {

    @Autowired
    AppConfig config;
    @Autowired
    DeptMapper deptMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    AgentMapper agentMapper;
    /**
    * 查询（并找出运营商id所对应的运营商名称）
    *
    * @Param: [id]
    * @Return: cc.yugu.yhdw.common.domain.basic.Dept
    * @Author By: zjn 2018/7/3  15:36
    */
    public Dept find(int id) {
        // 根据主键查询表bas_dept
        Dept dept = deptMapper.find(id);
        if (dept.getAgentId() != null && dept.getAgentId() != 0) {
            dept.setAgentName(agentMapper.find(dept.getAgentId()) != null ? agentMapper.find(dept.getAgentId()).getAgentName() : "");
        }
        if (dept.getParentId() != null && dept.getParentId() != 0) {
            dept.setParentName(deptMapper.find(dept.getParentId()) != null ? deptMapper.find(dept.getParentId()).getDeptName() : "");
        }
        return dept;
    }
    /**
    * 分页查询
    * 
    * @Param: [search]
    * @Return: cc.yugu.yhdw.common.entity.pagination.Page
    * @Author By: zjn 2018/7/3  15:40
    */ 
    public Page findPage(Dept search) {
        if (search.getAgentId() != null && search.getAgentId() == 0) {
            search.setAgentId(null);
        }
        if (search.getParentId() != null && search.getParentId() == 0) {
            search.setParentId(null);
        }
        Page page = search.buildPage();
        page.setTotalItems(deptMapper.findPageCount(search));
        search.setBeginIndex(page.getOffset());
        page.setResult(deptMapper.findPageResult(search));
        return page;
    }
    /**
    * 插入
    * 
    * @Param: [entity]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/3  15:40
    */ 
    public ExtResult insert(Dept entity) {
        try {
            entity.setCreateTime(new Date());
            if (entity.getParentId() != null && entity.getParentId() == 0) {
                entity.setParentId(null);
            }
            // 插入
            deptMapper.insert(entity);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 更新
    * 
    * @Param: [entity]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/3  15:42
    */ 
    public ExtResult update(Dept entity) {
        try {
            if (entity.getParentId() != null && entity.getParentId() == 0) {
                entity.setParentId(null);
            }
            deptMapper.update(entity);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 判断当前登录名是否存在
    * 
    * @Param: [deptId]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/3  15:43
    */ 
    public ExtResult hasRef(int deptId) {
        // 登录名 (表bas_user)
        String username = userMapper.hasRecordByProperty("deptId", deptId);
        if (StringUtils.isEmpty(username)) {
            return ExtResult.successResult();
        }
        return ExtResult.failResult(String.format("部门下有用户:%s不能删除", username));
    }
    /**
    * 删除
    * 
    * @Param: [id]
    * @Return: cc.yugu.yhdw.common.entity.json.ExtResult
    * @Author By: zjn 2018/7/3  15:46
    */ 
    public ExtResult delete(int id) {
        try {
            ExtResult result = hasRef(id);
            if (!result.isSuccess()) {
                return result;
            }
            deptMapper.delete(id);
        } catch (Exception e) {
            return ExtResult.failResult("操作失败");
        }
        return ExtResult.successResult();
    }
    /**
    * 输出构建的目录树
    * 
    * @Param: [checked, dummy, agentId, stream]
    * @Return: void
    * @Author By: zjn 2018/7/3  16:22
    */ 
    public void tree(Set<Integer> checked, String dummy, Integer agentId, OutputStream stream) throws IOException {
        List<Dept> deptList = new ArrayList<Dept>();
        if (agentId == null || agentId == 0) {
            deptList = deptMapper.findAll();
        } else {
            deptList = deptMapper.findByAgent(agentId);
        }
        Map<Integer, Dept> allMap = new HashMap<Integer, Dept>();
        List<Dept> topList = new ArrayList<Dept>();
        for (Dept dept : deptList) {
            allMap.put(dept.getId(), dept);
            if (dept.getParentId() == null) {
                topList.add(dept);
            }
        }

        List<Node<NodeModel>> roots = new ArrayList<Node<NodeModel>>();
        if (StringUtils.isNotEmpty(dummy)) {
            NodeModel data = new NodeModel();
            Node<NodeModel> root = new Node<NodeModel>(data);
            data.setId(0);
            data.setName(dummy);
            roots.add(root);

            for (Dept topDept : topList) {
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel, root);

                nodeModel.setId(topDept.getId());
                nodeModel.setName(topDept.getDeptName());
                nodeModel.setCheckStatus(checked.contains(topDept.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);
                privateMakeTree(checked, node, allMap, makeParentMap(allMap));
            }

        } else {
            for (Dept topDept : topList) {
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel);

                nodeModel.setId(topDept.getId());
                nodeModel.setName(topDept.getDeptName());
                nodeModel.setCheckStatus(checked.contains(topDept.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);
                privateMakeTree(checked, node, allMap, makeParentMap(allMap));
                roots.add(node);
            }
        }

        ObjectMapper objectMapper = new ObjectMapper();
        JsonGenerator json = objectMapper.getJsonFactory().createJsonGenerator(stream, JsonEncoding.UTF8);
        json.writeStartArray();
        YhdwUtils.writeJson(roots, json);
        json.writeEndArray();

        json.flush();
        json.close();
    }
    /**
    * 往父节点添加子节点
    *
    * @Param: [checked, parent, allMap, parentMap]
    * @Return: void
    * @Author By: zjn 2018/7/3  16:23
    */
    private void privateMakeTree(Set<Integer> checked, Node<NodeModel> parent, Map<Integer, Dept> allMap, Map<Integer, List<Integer>> parentMap) {
        List<Integer> sonIdList = parentMap.get(parent.getData().getId());
        if (sonIdList != null) {
            for (Integer id : sonIdList) {
                Dept dept = allMap.get(id);
                NodeModel nodeModel = new NodeModel();
                Node<NodeModel> node = new Node<NodeModel>(nodeModel);
                nodeModel.setId(dept.getId());
                nodeModel.setName(dept.getDeptName());
                nodeModel.setCheckStatus(checked.contains(dept.getId()) ? NodeModel.CheckedStatus.checked : NodeModel.CheckedStatus.unchecked);

                parent.addChild(node);

                privateMakeTree(checked, node, allMap, parentMap);
            }
        }
    }
    /**
    * 构建父节点
    *
    * @Param: [deptMap]
    * @Return: java.util.Map<java.lang.Integer,java.util.List<java.lang.Integer>>
    * @Author By: zjn 2018/7/3  16:24
    */
    private Map<Integer, List<Integer>> makeParentMap(Map<Integer, Dept> deptMap) {
        Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
        for (Map.Entry<Integer, Dept> entry : deptMap.entrySet()) {
            if (entry.getValue().getParentId() != null) {
                Integer parentId = entry.getValue().getParentId();
                List<Integer> v = map.get(parentId);
                if (v == null) {
                    map.put(parentId, v = new ArrayList<Integer>());
                }
                v.add(entry.getKey());
            }
        }

        return map;
    }

}
